home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 39
/
Amiga Format CD39 (1999-04-13)(Future Publishing)(GB)[!][issue 1999-05].iso
/
-seriously_amiga-
/
graphics
/
mpeg2decode
/
src
/
audio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-02
|
9KB
|
325 lines
/*** audio.c - MPEG Layer 1/2 audio handling in a MPEG stream ***/
/* (c) 1999 Jesper Svennevid */
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include "config.h"
#include "mpeg2dec.h"
#include "audio.h"
#include "global.h"
#include "mpegaudio/common.h"
#include "mpegaudio/decoder.h"
extern int Decode_Audio();
struct AudioBuffer
{
/* contains as a max */
unsigned char *databuffer;
struct AudioBuffer *next;
};
#define MAX_AUDIOBUFFER_SIZE 65536 /* size of one audio-buffer */
#define MAX_AUDIOFRAMES_DECODE 16 /* number of audio-frames to decode before flushing */
struct AudioBuffer *ab_current = NULL; /* current audio-buffer reading from */
struct AudioBuffer *ab_feed = NULL; /* current audio-buffer feeding into */
struct AudioBuffer *ab_free = NULL; /* free data-buffers */
/* writing offset into current buffer */
unsigned long feedOffset = NULL;
/* reading offset into current buffer */
unsigned long readOffset = NULL;
/* how much data present in the buffer */
unsigned long audioBufferSize = NULL;
void audio_feedbuffer( unsigned char *data )
{
if(ab_feed)
{
if(feedOffset>=MAX_AUDIOBUFFER_SIZE)
{
if(ab_free)
{
struct AudioBuffer *temp = ab_free;
ab_free = temp -> next;
temp -> next = NULL;
ab_feed -> next = temp;
ab_feed = temp;
}
else
{
struct AudioBuffer *temp = malloc(sizeof(struct AudioBuffer));
if(temp)
{
if( (temp -> databuffer = malloc(MAX_AUDIOBUFFER_SIZE)) )
{
temp -> next = NULL;
ab_feed -> next = temp;
ab_feed = temp;
}
else
exit(0);
}
else
exit(0);
}
feedOffset = NULL;
}
}
else
{
if( (ab_feed = malloc(sizeof(struct AudioBuffer))) )
{
if( !(ab_feed -> databuffer = malloc(MAX_AUDIOBUFFER_SIZE)) )
exit(0);
}
else
exit(0);
ab_current = ab_feed;
}
/* feed mpeg-audio data to buffer */
#ifdef STORM
ab_feed -> databuffer[feedOffset++] = (unsigned char)data;
#else
ab_feed -> databuffer[feedOffset++] = data;
#endif
audioBufferSize++;
}
unsigned char audio_pollbuffer()
{
if(ab_current)
{
if((ab_current==ab_feed)&&(readOffset>=feedOffset))
return 0x00;
if(readOffset>=MAX_AUDIOBUFFER_SIZE)
{
struct AudioBuffer *temp = ab_current -> next;
if(!temp) return 0x00;
ab_current -> next = ab_free;
ab_free = ab_current;
ab_current = temp;
readOffset = NULL;
}
if(audioBufferSize)
{
audioBufferSize--;
return ab_current -> databuffer[readOffset++];
}
}
return 0x00;
}
unsigned long audioOpened = NULL;
typedef short PCM[2][3][SBLIMIT];
PCM FAR *pcm_sample;
PCM FAR *pcm_sample_full;
typedef unsigned int SAM[2][3][SBLIMIT];
SAM FAR *sample;
SAM FAR *sample_full;
typedef double FRA[2][3][SBLIMIT];
FRA FAR *fraction;
FRA FAR *fraction_full;
typedef double VE[2][HAN_SIZE];
VE FAR *w;
VE FAR *w_full;
layer info;
int error_protection, crc_error_count, total_error_count;
unsigned int old_crc, new_crc;
unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT],
scale_index[2][3][SBLIMIT];
unsigned long bitsPerSlot, samplesPerFrame, frameNum = 0;
unsigned long frameBits, gotBits = 0;
char t[50];
int topSb = 0;
int notEnoughData = NULL;
int Decode_Audio()
{
int i,j,k,sync,stereo,clip;
static unsigned long sample_frames;
static Bit_stream_struc bs;
static frame_params fr_ps;
static int done;
static unsigned long bufferCounter;
extern FILE *pipe_file;
if(!Enable_Sound) return 0;
if(audioBufferSize<1024)
return 0; /* hmm, we should always have data to poll */
if(!audioOpened)
{
pcm_sample = (PCM FAR *) mem_alloc((long) sizeof(PCM), "PCM Samp");
sample = (SAM FAR *) mem_alloc((long) sizeof(SAM), "Sample");
fraction = (FRA FAR *) mem_alloc((long) sizeof(FRA), "fraction");
w = (VE FAR *) mem_alloc((long) sizeof(VE), "w");
done = FALSE;
bufferCounter = NULL;
fr_ps.header = &info;
fr_ps.tab_num = -1; /* no table loaded */
fr_ps.alloc = NULL;
for (i=0;i<HAN_SIZE;i++) for (j=0;j<2;j++) (*w)[j][i] = 0.0;
open_bit_stream_r(&bs, "", BUFFER_SIZE);
sample_frames = 0;
audioOpened = 1L;
}
if(done)
return 0;
//if(!notEnoughData)
//{
sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LNGTH);
frameBits = sstell(&bs) - gotBits;
gotBits += frameBits;
if (!sync) return 0;
decode_info(&bs, &fr_ps);
hdr_to_frps(&fr_ps);
//}
//else
// notEnoughData = NULL;
stereo = fr_ps.stereo;
error_protection = info.error_protection;
crc_error_count = 0;
total_error_count = 0;
//if(audioBufferSize<(((144*(bitrate[info.lay-1][info.bitrate_index]*1000)/((long)(s_freq[info.sampling_frequency]*1000)))+(info.padding?1:0))*2))
//{
// printf("out of data\n");
// notEnoughData = 1L;
// return 0;
//}
if(!pipe_file)
{
char buffer[256];
sprintf(buffer,"AUDIO:B 16 C %ld F %ld",stereo,((long)(s_freq[info.sampling_frequency]*1000)));
pipe_file = fopen(buffer,"w");
}
if (error_protection) buffer_CRC(&bs, &old_crc);
switch (info.lay) {
case 1: {
bitsPerSlot = 32; samplesPerFrame = 384;
I_decode_bitalloc(&bs,bit_alloc,&fr_ps);
I_decode_scale(&bs, bit_alloc, scale_index, &fr_ps);
clip = 0;
for (i=0;i<SCALE_BLOCK;i++) {
I_buffer_sample(&bs,(*sample),bit_alloc,&fr_ps);
I_dequantize_sample(*sample,*fraction,bit_alloc,&fr_ps);
I_denormalize_sample((*fraction),scale_index,&fr_ps);
if(topSb>0) /* clear channels to 0 */
for(j=topSb; j<fr_ps.sblimit; ++j)
for(k=0; k<stereo; ++k)
(*fraction)[k][0][j] = 0;
for (j=0;j<stereo;j++) {
clip += SubBandSynthesis (&((*fraction)[j][0][0]), j,
&((*pcm_sample)[j][0][0]));
}
if(pipe_file) out_fifo(*pcm_sample, 1, &fr_ps, done,
pipe_file, &sample_frames);
}
return 1;
}
case 2: {
bitsPerSlot = 8; samplesPerFrame = 1152;
II_decode_bitalloc(&bs, bit_alloc, &fr_ps);
II_decode_scale(&bs, scfsi, bit_alloc, scale_index, &fr_ps);
clip = 0;
for (i=0;i<SCALE_BLOCK;i++) {
II_buffer_sample(&bs,(*sample),bit_alloc,&fr_ps);
II_dequantize_sample((*sample),bit_alloc,(*fraction),&fr_ps);
II_denormalize_sample((*fraction),scale_index,&fr_ps,i>>2);
if(topSb>0) /* debug : clear channels to 0 */
for(j=topSb; j<fr_ps.sblimit; ++j)
for(k=0; k<stereo; ++k)
(*fraction)[k][0][j] =
(*fraction)[k][1][j] =
(*fraction)[k][2][j] = 0;
for (j=0;j<3;j++) for (k=0;k<stereo;k++) {
clip += SubBandSynthesis (&((*fraction)[k][j][0]), k,
&((*pcm_sample)[k][j][0]));
}
if(pipe_file) out_fifo(*pcm_sample, 3, &fr_ps, done, pipe_file,
&sample_frames);
}
return 1;
}
}
}
#ifdef STORM
void out_fifo(short FAR pcm_sample[2][3][SBLIMIT], int num, frame_params *fr_ps, int done, FILE *outFile, unsigned long *psampFrames)
#else
void out_fifo(pcm_sample, num, fr_ps, done, outFile, psampFrames)
short FAR pcm_sample[2][3][SBLIMIT];
int num;
frame_params *fr_ps;
int done;
FILE *outFile;
unsigned long *psampFrames;
#endif
{
int i,j,l;
int stereo = fr_ps->stereo;
int sblimit = fr_ps->sblimit;
static short int outsamp[1600];
static long k = 0;
for (i=0;i<num;i++) for (j=0;j<SBLIMIT;j++)
{
(*psampFrames)++;
for (l=0;l<stereo;l++)
{
if (!(k%(1600)) && k)
{
fwrite(outsamp,2,1600,outFile);
k = 0;
}
outsamp[k++] = pcm_sample[l][i][j];
}
}
}